package com.huayun.weexutil;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import com.huayun.util.utils.SharedPreferenceUtil;
import com.huayun.util.utils.Utils;
import com.huayun.viewutils.customview.ChooseView;
import com.huayun.viewutils.dialogutils.DialogUtil;
import com.huayun.viewutils.imageutil.inter_face.Action;
import com.taobao.weex.IWXRenderListener;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.common.WXRenderStrategy;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.huayun.util.utils.LogUtil;

import static com.huayun.viewutils.customview.ChooseView.SELECT_WEEX_URL;
import static com.huayun.weexutil.BuildConfig.DEBUG;

/**
 * 带下拉刷新的界面
 * Created by LZL on 2017/11/1.
 */

public class WeexUtil implements IWXRenderListener {
    private WXSDKInstance mWXSDKInstance;
    private ViewGroup parent;
    private Action<View> viewLoadSuccessListener;//页面和数据加载成功
    //    private Action1<String> viewReLoadListener;//js界面重新加载的监听
    private boolean viewCreateSuccess;//js界面渲染成功为true，否则为false。
    private boolean setDateViewCreate = true;
    private Object[] data;
    private String[] type;
    private View weexView;
    private View loadingView, errorView;
    private Context context;
    private Map<String, Object> options;
    private List<String> prefix;
    private ImageView errorImg;
    private TextView errorDec, errorAgain;
    private boolean showLoad, showError;
    private String jsUrl;//加载的js的完整路劲
//    public Action<String> getViewReLoadListener() {
//        return viewReLoadListener;
//    }
//
//    public void setViewReLoadListener(Action<String> viewReLoadListener) {
//        this.viewReLoadListener = viewReLoadListener;
//    }

    public WeexUtil(boolean showLoad, boolean showError, String uri, Map<String, Object> options, ViewGroup group, Context context) {
        this.showLoad = showLoad;
        this.showError = showError;
        this.jsUrl = uri;
        this.context = context;
        this.parent = group;
        this.options = options;
        init();
        loadUrl();
    }

    public WeexUtil(String uri, Map<String, Object> options, ViewGroup group, Context context) {
        this(true, true, uri, options, group, context);
    }

    public WeexUtil(String uri, ViewGroup group, Context context) {
        this(uri, null, group, context);
    }

    @SuppressLint("InflateParams")
    private void init() {
        errorView = LayoutInflater.from(context).inflate(R.layout.weex_load_error, null);
        loadingView = LayoutInflater.from(context).inflate(R.layout.weex_loading, null);
        initErrorView();
    }

    private void initErrorView() {
        errorImg = (ImageView) errorView.findViewById(R.id.img);
        errorDec = (TextView) errorView.findViewById(R.id.dec);
        errorAgain = (TextView) errorView.findViewById(R.id.try_again);
        errorView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                loadUrl();
            }
        });
        errorView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                selectWeexUrl();
                return false;
            }
        });
    }

    private void loadUrl() {
        parent.removeAllViews();
        if (showLoad) {
            parent.addView(loadingView);
        }
        if (mWXSDKInstance != null) {
            mWXSDKInstance.destroy();
        }
        mWXSDKInstance = new WXSDKInstance(context);
        mWXSDKInstance.registerRenderListener(this);
        if (jsUrl != null) {
            File file = new File(jsUrl);
            Uri jsUri = Uri.parse(jsUrl);
            String scheme = jsUri.getScheme();
            if (TextUtils.isEmpty(scheme) && !file.exists()) {
                jsUrl = getUrl(jsUrl);
            }
            read(jsUrl);
        }
    }

    /**
     * 读取js文件
     */
    private void read(String uri) {
        setDateViewCreate = false;
        mWXSDKInstance.renderByUrl(context.getPackageName(), uri, options, null, WXRenderStrategy.APPEND_ASYNC);
    }

    public void setData(Object... data) {
        this.data = data;
    }

    public void setType(String... type) {
        this.type = type;
    }

    public void fireFresh() {
        fireFresh(true);
    }

    public void fireFresh(boolean addViewDelay) {
        if (viewCreateSuccess) {
            setDateViewCreate = true;
            if (Utils.notNull(data) && Utils.notNull(type) && data.length == type.length) {
                for (int i = 0; i < data.length; i++) {
                    setData(data[i], type[i], addViewDelay);
                }
            } else {
                if (Utils.isNull(data) && Utils.isNull(type)) {
                    setData(null, null, addViewDelay);
                } else {
                    throw new RuntimeException("data type must have same length");
                }
            }
        } else {
            setDateViewCreate = false;
        }

    }

    private void setData(Object data, String type, boolean addViewDelay) {
        fireGlobalEvent(data, type, addViewDelay);
    }

    public void setViewLoadSuccessListener(Action<View> viewLoadSuccessListener) {
        this.viewLoadSuccessListener = viewLoadSuccessListener;
    }

    private void fireGlobalEvent(Object data, String type, boolean addViewDelay) {
        if (mWXSDKInstance != null && Utils.notNull(data)) {
            Map<String, Object> params = new HashMap<>();
            params.put("jsonData", data);
            //触发刷新操作 只更新数据 不重载页面
            mWXSDKInstance.fireGlobalEventCallback(type, params);
        }
    }

    public String getUrl(String jsName) {
        String prefix = (String) SharedPreferenceUtil.get("prefix_weex_url", "");
        String url = "";
        if (TextUtils.isEmpty(prefix)) {
            url = "";
        } else {
            url = prefix + jsName + ".js";
        }
        return url;
    }

    @Override
    public void onViewCreated(WXSDKInstance wxsdkInstance, View view) {
        weexView = view;

        addView(view);
    }

    @Override
    public void onRenderSuccess(WXSDKInstance wxsdkInstance, int i, final int i1) {
        viewCreateSuccess = true;
        if (!setDateViewCreate) {
            fireFresh();
        }
    }

    @Override
    public void onRefreshSuccess(WXSDKInstance wxsdkInstance, int i, int i1) {
    }

    @Override
    public void onException(WXSDKInstance wxsdkInstance, String errorCode, String msg) {
        LogUtil.e("errorCode=" + errorCode + "\nmsg=" + msg + "\n" + wxsdkInstance.getBundleUrl());
        if (!errorCode.equals("-1002")) {
            if (showError) {
                showErrorUnSopport();
                addView(errorView);
            }
        } else {
            viewCreateSuccess = false;
            if (showError) {
                DialogUtil dialogUtil = new DialogUtil(new WeakReference<Activity>((Activity) context));
                dialogUtil.setTop("提示").setContent(msg).setButtonShowType(DialogUtil.BUTTON_TYPE_ONE_BTN).show();
                addView(errorView);
            }

        }
    }

    private void loadLocal() {
        if (mWXSDKInstance != null) {
            mWXSDKInstance.destroy();
        }
        mWXSDKInstance = new WXSDKInstance(context);
        mWXSDKInstance.registerRenderListener(this);

        mWXSDKInstance.renderByUrl(context.getPackageName(), "file:///js/" + jsUrl + ".weex.js", options, null, WXRenderStrategy.APPEND_ASYNC);
    }

    private void loadH5() {
//        parent.removeAllViews();
//        X5WebView webView = new X5WebView(context, null);
//        webView.setLoadSuccessListener(new Action1<WebView>() {
//            @Override
//            public void call(WebView view) {
//                parent.removeView(loadingView);
//            }
//        });
//        parent.addView(webView);
//        ViewGroup.LayoutParams layoutParams = webView.getLayoutParams();
//        layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
//        layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
//        webView.setLayoutParams(layoutParams);
//        if (showLoad) {
//            parent.addView(loadingView);
//        }
//        webView.loadUrl(getHtmlUrl(h5Server + jsName + ".html"));
    }

    private String getHtmlUrl(String shareUrl) {
//        if (Utils.notNull(options)) {
//            shareUrl += "?";
//            Iterator<Map.Entry<String, Object>> entryIterator = options.entrySet().iterator();
//            String key;
//            String value;
//            StringBuilder shareUrlBuilder = new StringBuilder(shareUrl);
//            for (Map.Entry<String, Object> entry : options.entrySet()) {
//
//                key = entry.getKey();
//                value = (String) entry.getValue();
//                value = URLEncoder.encode(value);
//                if (key.equals("hot-reload_controller") || key.equals("_wx_tpl") || key.equals("bundleUrl")) {
//                    continue;
//                }
//                shareUrlBuilder.append(key).append("=").append(value).append("&");
//            }
//            shareUrl = shareUrlBuilder.toString();
//            shareUrl = shareUrl.substring(0, shareUrl.length() - 1);
//        }
//        return shareUrl;
        return "";
    }

    private void addView(View view) {
        addView(view, true);
    }

    /**
     * @param view          need add view
     * @param showViewDelay true:show delay,cause by weexView attached has some animation
     */
    private void addView(final View view, boolean showViewDelay) {
        if (showViewDelay) {
            view.setVisibility(View.INVISIBLE);
        }
        parent.removeAllViews();
        parent.addView(view);
        //        if (view instanceof X5WebView) {
        //            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        //            layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
        //            layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
        //            view.setLayoutParams(layoutParams);
        //        }
        if (showViewDelay) {
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    view.setVisibility(View.VISIBLE);
                    if (viewLoadSuccessListener != null) {
                        viewLoadSuccessListener.call(view);
                    }
                }
            }, 100);
        }
    }

    public void selectWeexUrl() {
        if (DEBUG) {
            if (prefix == null) {
                prefix = new ArrayList<>();
                prefix.add("http://192.168.8.190:8081/dist/");
            }
            ChooseView chooseView = new ChooseView(context, SELECT_WEEX_URL);
            chooseView.setList(prefix);
            chooseView.setChooseBack(new Action<Integer>() {
                @Override
                public void call(Integer integer) {
                    SharedPreferenceUtil.put("prefix_weex_url", prefix.get(integer));
                    loadUrl();
                }
            });
            chooseView.setSearchCall(new Action<String>() {
                @Override
                public void call(String s) {
                    SharedPreferenceUtil.put("prefix_weex_url", s);
                    loadUrl();
                }
            });
            chooseView.show();
        }
    }

    private void showErrorUnSopport() {
        //errorImg.setImageResource(R.drawable.empty);
        errorDec.setText("十分抱歉，加载的时候出了一些问题,点击按钮可以加载网页版，但是可能会有一些问题。");
        errorAgain.setText("点击加载");
        errorView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loadH5();
            }
        });

    }

    public void destroy() {
        if (mWXSDKInstance != null) {
            mWXSDKInstance.destroy();
        }
        data = null;
        type = null;
        weexView = null;
        if (parent != null) {
            parent.removeAllViews();
        }
        parent = null;
        context = null;
    }
}
